package com.moxingzhegroup.activity;

import android.Manifest;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.widget.VideoView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;

import com.moxingzhegroup.AutoUpdater;
import com.moxingzhegroup.Constants;
import com.moxingzhegroup.R;
import com.moxingzhegroup.base.BaseActivity;
import com.moxingzhegroup.entity.Advertisement;
import com.moxingzhegroup.presenter.VideoPresenter;
import com.moxingzhegroup.presenter.callback.IVideoCallback;
import com.moxingzhegroup.util.LogWatcher;
import com.umeng.analytics.MobclickAgent;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @author LiaoRun
 */
public class MainActivity extends BaseActivity {

    /**
     * 请求权限的标识
     */
    private static final int REQUIRED_PERMISSIONS_REQUEST = 0;
    private static final String TAG = "MainActivity";
    private VideoView mVideoView;

    private VideoPresenter mVideoPresenter;

    /**
     * 当前播放的列表
     */
    private final ArrayList<Advertisement> mCurrentVideoList = new ArrayList<>();
    private final ArrayList<BroadcastReceiver> mBroadcastReceiver = new ArrayList<>();

    /**
     * VideoPresenter 的事件回调
     */
    private IVideoCallback mVideoCallback;


    private int mCurrentPlayingVideoIndex = 0;


    private Button buttonPlay;
    private Context context;
    private MediaController mMediaController;
    private boolean mIsPrevOrNextFlag = true;
    private LinkedList<Advertisement> mDownloadVideoQueue;
    private File mVideoSavePath;
    /**
     * 记录本地有多少可以播放的视频
     */
    private int mCurrentCacheVideoSize = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        // check update
        checkUpdate();

        // init object
        initObject();

        // init permission
        initPermission(context);


        // init presenter
        initPresenter();

        // init view
        initView();


        //获取需要播放的视频列表
        // init data
        // 10 分钟更新一次播放列表

        initData();


        initListener();


    }

    private void initData() {


        Log.d(TAG, "run: 去获取了一次视频列表变化");

        mVideoPresenter.getAdvertisementInfo();
    }

    /**
     * 检查app 是否有更新
     */
    private void checkUpdate() {
        //检查更新
        try {
            //6.0才用动态权限
            if (Build.VERSION.SDK_INT >= 23) {
                String[] permissions = {
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
//                        Manifest.permission.ACCESS_WIFI_STATE,
                        Manifest.permission.INTERNET};
                List<String> permissionList = new ArrayList<>();
                for (String permission : permissions) {
                    if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                        permissionList.add(permission);
                    }
                }
                if (permissionList.size() <= 0) {
                    //说明权限都已经通过，可以做你想做的事情去
                    //自动更新
                    AutoUpdater manager = new AutoUpdater(MainActivity.this);
                    manager.checkUpdate();
                } else {
                    //存在未允许的权限
                    ActivityCompat.requestPermissions(this, permissions, 100);
                }
            } else {
                AutoUpdater manager = new AutoUpdater(MainActivity.this);
                manager.checkUpdate();
            }
        } catch (Exception ex) {
            Log.d(TAG, "checkUpdate: 自动更新异常");
            Toast.makeText(MainActivity.this, "自动更新异常：" + ex.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

    private void initView() {
        // 尝试让视频铺满控件

        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT,
                RelativeLayout.LayoutParams.FILL_PARENT);

        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
        mVideoView.setLayoutParams(layoutParams);

    }

    private void initPermission(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

                String[] needPermissions = new String[1];

                needPermissions[0] = Manifest.permission.WRITE_EXTERNAL_STORAGE;

                ActivityCompat.requestPermissions(this, needPermissions, REQUIRED_PERMISSIONS_REQUEST);
            }
        }
    }

    private void initPresenter() {

        mVideoPresenter = new VideoPresenter();

        mVideoCallback = new IVideoCallback() {
            @Override
            public void onNewVideoFileBeginDownload(Long downloadId, String videoFileName) {

                listener(downloadId, videoFileName);
            }

            @Override
            public void onAllAdvertisementLoad(List<Advertisement> advertisements) {

                if (advertisements.size() == 0) {

                    Toast.makeText(MainActivity.this, "后台没有视频", Toast.LENGTH_SHORT).show();
                    Log.d(TAG, "onVideoFilesLoaded: 后台没有视频");
                    return;
                }


                // 修改为先下载KB 为单位的文件，在下载以MB 为单位的文件，
                // 且一个一个下载，防止一起下载太慢了
                // 已完成

                mDownloadVideoQueue = new LinkedList<>();

                for (Advertisement videoFile : advertisements) {
                    if (videoFile.getSize().contains("KB")) {
                        mDownloadVideoQueue.add(videoFile);
                    }
                }

                for (Advertisement videoFile : advertisements) {
                    if (videoFile.getSize().contains("MB")) {
                        mDownloadVideoQueue.add(videoFile);
                    }
                }

                downLoadNextVideo();

                // 保存需要播放的队列
                for (Advertisement advertisement : advertisements) {
                    // 只播放未下架的视频
                    if (advertisement.getStatus() == 1) {
                        mCurrentVideoList.add(advertisement);
                    }
                }

                // 初始化播放列表完成
                // 开始播放
                Log.d(TAG, "onAllAdvertisementLoad: 初始化播放列表完成,开始播放");

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        play();
                    }
                });
            }

            @Override
            public void onNetworkError(String message) {
                Log.d(TAG, "网络错误，暂时播放本地缓存视频，错误信息：" + message);

                // 网络错误时，直接播放本地广告
                File[] files = mVideoSavePath.listFiles();

                assert files != null;
                for (File file : files) {
                    if (file.isFile()) {
                        // 历史遗留问题，导致限制播放的视频都不是已 mp4结尾的
                        if (!file.getName().endsWith("mp4")) {
                            mCurrentVideoList.add(new Advertisement(file.getName()));
                        }
                    }
                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (mCurrentVideoList.size() > 0) {
                            Toast.makeText(MainActivity.this, "网络错误，暂时播放本地缓存视频，错误信息：" + message, Toast.LENGTH_SHORT).show();
                            play();
                        } else {
                            Toast.makeText(MainActivity.this, "网络错误，且本地没有缓存的视频可以播放，错误信息：" + message, Toast.LENGTH_SHORT).show();
                        }
                    }
                });

            }

            @Override
            public void onLoading() {

            }

            @Override
            public void onEmpty() {

            }

            @Override
            public void onFailure() {

            }
        };
        mVideoPresenter.registerViewCallback(mVideoCallback);
    }


    /**
     * 下载下一个视频，如果下载的队列中还有元素
     */
    private void downLoadNextVideo() {
        if (!mDownloadVideoQueue.isEmpty()) {
            // 先在本地删除，在下载， 保证本地的视频和服务器的一致

            Advertisement advertisement = mDownloadVideoQueue.pop();

            File file = new File(Constants.getVideoPath() + File.separator + advertisement.getName());

            if (file.exists()) {
                if (advertisement.getStatus() == 2L) {
                    if (file.delete()) {
                        Log.d(TAG, "onVideoFilesLoaded: 删除成功" + file.getAbsolutePath());

                        // 更新播放的视频列表

                        Iterator<Advertisement> iterator = mCurrentVideoList.iterator();


                        while (iterator.hasNext()) {
                            Advertisement videoFile1 = iterator.next();
                            if (advertisement.getName().equals(videoFile1.getName())) {


                                iterator.remove();
                            }
                        }


                    } else {
                        Log.d(TAG, "onVideoFilesLoaded: 删除状态为2.不需要的视频失败" + file.getAbsolutePath());
                    }
                }


                // 当前视频已经存在不需要下载了,直接下载队列中下一个视频
                Log.d(TAG, "downLoadNextVideo: 当前视频已经存在不需要下载了,直接下载队列中下一个视频");
                downLoadNextVideo();

            } else {
                Log.d(TAG, "onVideoFilesLoaded: 文件不存在" + file.getAbsolutePath());

                if (advertisement.getStatus() == 2L) {
                    // 禁用的状态，下载下一个
                    downLoadNextVideo();
                } else {
                    // 文件不存在,且是启用的状态，需要下载
                    mVideoPresenter.downloadVideos(advertisement, getBaseContext());
                }

            }

        } else {
            Log.d(TAG, "downLoadNextVideo: 没有下载任务了");
        }
    }

    private void initObject() {
        mVideoSavePath = new File(Constants.getVideoPath());

        // 自己决定的存储路径要自己创建
        if (!mVideoSavePath.exists()) {
            if (!mVideoSavePath.mkdir()) {
                Log.d(TAG, "initObject: 创建存放视频的路径失败");
                return;
            }
        }

        context = getBaseContext();

        mVideoView = findViewById(R.id.video_view);

        mMediaController = new MediaController(this);
        mVideoView.setMediaController(mMediaController);

        buttonPlay = findViewById(R.id.buttonPlay);
//        buttonStop = findViewById(R.id.buttonStop);


    }

    private void initListener() {

        mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                // 设置完播放地址，异步准备好播放了，开始播放

                mVideoView.start();
            }
        });

        mMediaController.setPrevNextListeners(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                mIsPrevOrNextFlag = true;
                playNextVideo();
            }
        }, new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                mIsPrevOrNextFlag = false;
                playPrevVideo();
            }
        });

        mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {

            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {

                Advertisement advertisement = mCurrentVideoList.get(mCurrentPlayingVideoIndex);
                Log.d(TAG, "onError: 第" + advertisement.getName() + "个视频播放出错:" + what + "----" + extra);
                Toast.makeText(context, "onError: 第" + advertisement.getName() + "个视频播放出错:" + what + "----" + extra, Toast.LENGTH_SHORT).show();

                // 发生错误重新播放
                if (mIsPrevOrNextFlag) {
                    playNextVideo();
                } else {
                    playPrevVideo();
                }

                return true;
            }
        });

        buttonPlay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                play();
            }
        });



        /*
         * 视频播放完之后需要实现自动播放下一个视频
         */
        mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {

                Log.d(TAG, "onCompletion: 一个视频播放完了");

                playNextVideo();

                // change flag
                mIsPrevOrNextFlag = true;
            }
        });

    }

    private void playPrevVideo() {
        // Resets the MediaPlayer to its uninitialized state.
        // After calling this method, you will have to initialize it again by setting the data source and calling prepare().


        mCurrentPlayingVideoIndex--;

        if (mCurrentPlayingVideoIndex < 0) {
            mCurrentPlayingVideoIndex = mCurrentVideoList.size() - 1;
        }

        play();
    }

    private void playNextVideo() {
        // Resets the MediaPlayer to its uninitialized state.
        // After calling this method, you will have to initialize it again by setting the data source and calling prepare().


        mCurrentPlayingVideoIndex++;

        if (mCurrentPlayingVideoIndex > mCurrentVideoList.size() - 1) {
            mCurrentPlayingVideoIndex = 0;
        }

        play();
    }


    private void listener(final long id, String videoFileName) {

        // 注册广播监听系统的下载完成事件。
        IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                long downloadFinishId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
                if (downloadFinishId == id) {
                    Toast.makeText(getApplicationContext(), "任务:" + id + " 下载完成!", Toast.LENGTH_LONG).show();

                    // 检查下载的文件大小是否大于0，才是下载的正确文件
                    File downloadNewFile = new File(Constants.getVideoPath() + File.separator + videoFileName);
                    if (downloadNewFile.length() > 0) {
                        // 更新播放的视频列表
                        // 下载成功也不需要添加到播放列表，因为一开始就把所有需要播放的添加到列表了
                        Log.d(TAG, "onReceive: 一个视频下载成功");
                        if (mCurrentCacheVideoSize == 0) {
                            mCurrentCacheVideoSize++;
                            play();
                        }

                    } else {
                        if (downloadNewFile.delete()) {
                            Log.d(TAG, "onReceive: 下载的空文件删除成功");
                        } else {
                            Log.d(TAG, "onReceive: 下载的空文件删除失败");
                        }
                    }

                    // 上一个下载任务完成了，可以下载下一个视频了
                    downLoadNextVideo();
                }
            }
        };

        mBroadcastReceiver.add(broadcastReceiver);
        registerReceiver(broadcastReceiver, intentFilter);
    }


    @Override
    public void onRequestPermissionsResult(
            int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUIRED_PERMISSIONS_REQUEST) {
            int index = 0;
            Map<String, Integer> permissionsMap = new HashMap<>();
            for (String permission : permissions) {
                permissionsMap.put(permission, grantResults[index]);
                index++;
            }

            if (permissionsMap.containsKey(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                permissionsMap.get(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            }
            //
            // Call your code from here

        }

        boolean hasPermission = false;
        if (100 == requestCode) {
            for (int grantResult : grantResults) {
                if (grantResult == -1) {
                    hasPermission = true;
                    break;
                }
            }
            if (hasPermission) {
                //跳转到系统设置权限页面，或者直接关闭页面，不让他继续访问
                permissionDialog();
            } else {
                //全部权限通过，可以进行下一步操作
                AutoUpdater manager = new AutoUpdater(MainActivity.this);
                manager.checkUpdate();
            }
        }

    }

    AlertDialog alertDialog;

    /**
     * 打开手动设置应用权限
     */
    private void permissionDialog() {
        if (alertDialog == null) {
            alertDialog = new AlertDialog.Builder(this)
                    .setTitle("提示信息")
                    .setMessage("当前应用缺少必要权限，该功能暂时无法使用。如若需要，请单击【确定】按钮前往设置中心进行权限授权。")
                    .setPositiveButton("设置", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            cancelPermissionDialog();
                            Uri packageUri = Uri.parse("package:" + getPackageName());
                            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageUri);
                            startActivity(intent);
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            cancelPermissionDialog();
                        }
                    })
                    .create();
        }
        alertDialog.show();
    }

    private void cancelPermissionDialog() {
        alertDialog.cancel();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        for (BroadcastReceiver broadcastReceiver : mBroadcastReceiver) {
            unregisterReceiver(broadcastReceiver);
        }

        if (mVideoPresenter != null) {
            mVideoPresenter.unRegisterViewCallback(mVideoCallback);
        }

        // 停止记录log
        LogWatcher.getInstance().stopWatch();

//        handler.removeCallbacks(runnable);
    }


    @Override
    public void onResume() {
        super.onResume();
        MobclickAgent.onResume(this);
    }

    @Override
    public void onPause() {
        super.onPause();
        MobclickAgent.onPause(this);
    }


    /**
     * 开始播放
     */
    protected void play() {

        Log.d(TAG, "onCompletion: " + mCurrentPlayingVideoIndex);
        Log.d(TAG, "onCompletion: " + mCurrentVideoList.size());

        // 本地没有一个视频的时候不能播放不然似乎要奔溃
        if (mVideoSavePath.exists()) {
            File[] listFiles = mVideoSavePath.listFiles();
            if (listFiles == null || listFiles.length <= 0) {
                Toast.makeText(MainActivity.this, "没有可播放的本地视频", Toast.LENGTH_SHORT).show();
                return;
            } else {
                mCurrentCacheVideoSize = listFiles.length;
            }
        } else {
            Toast.makeText(MainActivity.this, "缓存路径不存在，没有可以播放的视频", Toast.LENGTH_SHORT).show();
            return;
        }

        String videoPath = Constants.getVideoPath() + File.separator + mCurrentVideoList.get(mCurrentPlayingVideoIndex).getName();

        Uri uri = Uri.fromFile(new File(videoPath));

        Log.d(TAG, "play: videoPath" + videoPath);
        Log.d(TAG, "play: uri" + uri.getPath());

        mVideoView.setVideoURI(uri);
    }


}